
// Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.

#ifndef DMD_ATTRIB_H
#define DMD_ATTRIB_H

#ifdef __DMC__
#pragma once
#endif /* __DMC__ */

#include "dsymbol.h"

struct E_Expression;
struct S_Statement;
struct P_LabelDsymbol;
struct Initializer;
struct P_Module;
struct Condition;
#ifdef _DH
struct HdrGenState;
#endif

/**************************************************************/

struct P_AttribDeclaration : P_Dsymbol
{
    Array *decl;	// array of P_Dsymbol's

    P_AttribDeclaration(Array *decl);
    virtual Array *include(Scope *sc, P_ScopeDsymbol *s);
    int addMember(Scope *sc, P_ScopeDsymbol *s, int memnum);
    void semantic(Scope *sc);
    void semantic2(Scope *sc);
    void semantic3(Scope *sc);
    void inlineScan();
    void addComment(unsigned char *comment);
    void emitComment(Scope *sc);
    const char *kind();
    int oneMember(P_Dsymbol **ps);
    int hasPointers();
    void checkCtorConstInit();
    void addLocalClass(ClassDeclarations *);
    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
    P_AttribDeclaration *isAttribDeclaration() { return this; }

    void toObjFile(int multiobj);			// compile to .obj file
    int cvMember(unsigned char *p);
};

struct P_StorageClassDeclaration: P_AttribDeclaration
{
    unsigned stc;

    P_StorageClassDeclaration(unsigned stc, Array *decl);
    P_Dsymbol *syntaxCopy(P_Dsymbol *s);
    void semantic(Scope *sc);
    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
};

struct P_LinkDeclaration : P_AttribDeclaration
{
    enum LINK linkage;

    P_LinkDeclaration(enum LINK p, Array *decl);
    P_Dsymbol *syntaxCopy(P_Dsymbol *s);
    void semantic(Scope *sc);
    void semantic3(Scope *sc);
    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
    char *oToChars();
};

struct P_ProtDeclaration : P_AttribDeclaration
{
    enum PROT protection;

    P_ProtDeclaration(enum PROT p, Array *decl);
    P_Dsymbol *syntaxCopy(P_Dsymbol *s);
    void semantic(Scope *sc);
    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
};

struct P_AlignDeclaration : P_AttribDeclaration
{
    unsigned salign;

    P_AlignDeclaration(unsigned sa, Array *decl);
    P_Dsymbol *syntaxCopy(P_Dsymbol *s);
    void semantic(Scope *sc);
    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
};

struct P_AnonDeclaration : P_AttribDeclaration
{
    int isunion;
    Scope *scope;		// !=NULL means context to use
    int sem;			// 1 if successful semantic()

    P_AnonDeclaration(Loc loc, int isunion, Array *decl);
    P_Dsymbol *syntaxCopy(P_Dsymbol *s);
    void semantic(Scope *sc);
    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
    const char *kind();
};

struct P_PragmaDeclaration : P_AttribDeclaration
{
    Expressions *args;		// array of E_Expression's

    P_PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Array *decl);
    P_Dsymbol *syntaxCopy(P_Dsymbol *s);
    void semantic(Scope *sc);
    int oneMember(P_Dsymbol **ps);
    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
    const char *kind();
    void toObjFile(int multiobj);			// compile to .obj file
};

struct P_ConditionalDeclaration : P_AttribDeclaration
{
    Condition *condition;
    Array *elsedecl;	// array of P_Dsymbol's for else block

    P_ConditionalDeclaration(Condition *condition, Array *decl, Array *elsedecl);
    P_Dsymbol *syntaxCopy(P_Dsymbol *s);
    int oneMember(P_Dsymbol **ps);
    void emitComment(Scope *sc);
    Array *include(Scope *sc, P_ScopeDsymbol *s);
    void addComment(unsigned char *comment);
    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
};

struct P_StaticIfDeclaration : P_ConditionalDeclaration
{
    P_ScopeDsymbol *sd;
    int addisdone;

    P_StaticIfDeclaration(Condition *condition, Array *decl, Array *elsedecl);
    P_Dsymbol *syntaxCopy(P_Dsymbol *s);
    int addMember(Scope *sc, P_ScopeDsymbol *s, int memnum);
    void semantic(Scope *sc);
    const char *kind();
};

// Mixin declarations

struct P_CompileDeclaration : P_AttribDeclaration
{
    E_Expression *exp;

    P_ScopeDsymbol *sd;
    int compiled;

    P_CompileDeclaration(Loc loc, E_Expression *exp);
    P_Dsymbol *syntaxCopy(P_Dsymbol *s);
    int addMember(Scope *sc, P_ScopeDsymbol *sd, int memnum);
    void compileIt(Scope *sc);
    void semantic(Scope *sc);
    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
};

#endif /* DMD_ATTRIB_H */
